#include "oled.h"
#include "main.h"
#include "stm32f103xb.h"
#include "stm32f1xx_hal.h"

// CLK SDA RED DC
GPIO_TypeDef * OLED_PORT[] = {OLED_CLK_GPIO_Port, OLED_DO_GPIO_Port, OLED_RST_GPIO_Port, OLED_DC_GPIO_Port};
uint16_t OLED_PIN[] = {OLED_CLK_Pin, OLED_DO_Pin, OLED_RST_Pin, OLED_DC_Pin };

#define PIN_CLR(i) HAL_GPIO_WritePin(OLED_PORT[i], OLED_PIN[i], GPIO_PIN_RESET)
#define PIN_SET(i) HAL_GPIO_WritePin(OLED_PORT[i], OLED_PIN[i], GPIO_PIN_SET)

#define OLED_SCLK_Clr() PIN_CLR(0)
#define OLED_SCLK_Set() PIN_SET(0)

#define OLED_SDIN_Clr() PIN_CLR(1)
#define OLED_SDIN_Set() PIN_SET(1)

#define OLED_RST_Clr() PIN_CLR(2)
#define OLED_RST_Set() PIN_SET(2)

#define OLED_DC_Clr() PIN_CLR(3)
#define OLED_DC_Set() PIN_SET(3)

const uint8_t F6x8[][6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
		0x14, 0x7f, 0x14, 0x7f, 0x14, 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x00,
		0x62, 0x64, 0x08, 0x13, 0x23, 0x00, 0x36, 0x49, 0x55, 0x22, 0x50, 0x00,
		0x00, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, 0x00,
		0x00, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, 0x00,
		0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, 0x00,
		0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00,
		0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
		0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, 0x00,
		0x21, 0x41, 0x45, 0x4B, 0x31, 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
		0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, 0x00,
		0x01, 0x71, 0x09, 0x05, 0x03, 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
		0x06, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, 0x00,
		0x00, 0x56, 0x36, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00,
		0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
		0x02, 0x01, 0x51, 0x09, 0x06, 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, 0x00,
		0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
		0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00,
		0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
		0x3E, 0x41, 0x49, 0x49, 0x7A, 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
		0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
		0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
		0x7F, 0x02, 0x0C, 0x02, 0x7F, 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
		0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
		0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
		0x46, 0x49, 0x49, 0x49, 0x31, 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, 0x00,
		0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
		0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
		0x07, 0x08, 0x70, 0x08, 0x07, 0x00, 0x61, 0x51, 0x49, 0x45, 0x43, 0x00,
		0x00, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, 0x00,
		0x00, 0x41, 0x41, 0x7F, 0x00, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
		0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00,
		0x20, 0x54, 0x54, 0x54, 0x78, 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, 0x00,
		0x38, 0x44, 0x44, 0x44, 0x20, 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, 0x00,
		0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, 0x00,
		0x18, 0xA4, 0xA4, 0xA4, 0x7C, 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
		0x00, 0x44, 0x7D, 0x40, 0x00, 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, 0x00,
		0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
		0x7C, 0x04, 0x18, 0x04, 0x78, 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
		0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, 0x00,
		0x18, 0x24, 0x24, 0x18, 0xFC, 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
		0x48, 0x54, 0x54, 0x54, 0x20, 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, 0x00,
		0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
		0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
		0x1C, 0xA0, 0xA0, 0xA0, 0x7C, 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x14,
		0x14, 0x14, 0x14, 0x14, 0x14, };

void OLED_DELAY() {
	int i = 8;
	while(i--);
}

void OLED_WR_Byte(uint8_t dat, uint8_t cmd) {
	uint8_t i;
	if (cmd)
		OLED_DC_Set();
	else
		OLED_DC_Clr();
	for (i = 0; i < 8; i++) {
		OLED_SCLK_Clr();
		if (dat & 0x80)
			OLED_SDIN_Set();
		else
			OLED_SDIN_Clr();
		OLED_SCLK_Set();
		dat <<= 1;
	}
	OLED_DC_Set();
}

void OLED_SetPos(uint8_t x, uint8_t y) {
	OLED_WR_Byte(0xb0 + y, OLED_CMD);
	OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD);
	OLED_WR_Byte((x & 0x0f) | 0x01, OLED_CMD);
}

void OLED_DisplayOn(void) {
	OLED_WR_Byte(0X8D, OLED_CMD);
	OLED_WR_Byte(0X14, OLED_CMD);
	OLED_WR_Byte(0XAF, OLED_CMD);
}

void OLED_DisplayOff(void) {
	OLED_WR_Byte(0X8D, OLED_CMD);
	OLED_WR_Byte(0X10, OLED_CMD);
	OLED_WR_Byte(0XAE, OLED_CMD);
}

void OLED_Clear(void) {
	uint8_t i, n;
	for (i = 0; i < 8; i++) {
		OLED_WR_Byte(0xb0 + i, OLED_CMD);
		OLED_WR_Byte(0x00, OLED_CMD);
		OLED_WR_Byte(0x10, OLED_CMD);
		for (n = 0; n < 128; n++)
			OLED_WR_Byte(0, OLED_DATA);
	}
}

void OLED_Print(uint8_t x, uint8_t y, char *str) {
	OLED_SetPos(x, y);
	uint8_t i = 0, j, c;
	
	while (str[i] != '\0') {
		c = str[i] - ' ';
		for (j = 0; j < 6; ++j) {
			OLED_WR_Byte(F6x8[c][j], OLED_DATA);
		}
		x += 6;
		if (x > 122) {
			return;
		}
		++i;
	}
	
}

void OLED_PrintI(uint8_t x, uint8_t y , int value){
   int i=0,j,m=1,n=1;
	 unsigned char str[10];
   
   while(m!=0)
   {
     n=n*10;
     m=value/n;
     i++;
   }

   for(j=0;j<i;j++)
   {
      n=n/10;
      str[j]=(char)(value/n+48);
      value=value%n;
   }
   str[j]='\0';
   OLED_Print(x,y,(char*)str);   

}

void OLED_PrintInv(uint8_t x, uint8_t y, char *str) {
	OLED_SetPos(x, y);
	uint8_t i = 0, j, c;
	while (str[i] != '\0') {
		c = str[i] - ' ';
		for (j = 0; j < 6; ++j) {
			OLED_WR_Byte(~F6x8[c][j], OLED_DATA);
		}
		x += 6;
		if (x > 122) {
			return;
		}
		++i;
	}
	OLED_WR_Byte(0xFF, OLED_DATA);
}

inline void OLED_DrawRP(uint8_t y, uint8_t len) {
	OLED_SetPos(0, y);
	for(uint8_t i=0;i<len;++i) {
		OLED_WR_Byte(0xff, OLED_DATA);
	}
	for(uint8_t i=len;i<128;++i) {
		OLED_WR_Byte(0x00, OLED_DATA);
	}
}



// void OLED_DrawRect(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
// {
//   	uint8_t n;
// 	OLED_SetPos(x1, y1 >> 3);
// 	for (n = x1; n <= x2; n++)
// 	{
// 		OLED_WR_Byte(~((0x01 << (y1 % 8) + 1) - 1), OLED_DATA);
// 	}
// 	for (uint8_t y = (y1 >> 3) + 1; y < (y2 >> 3); ++y) {
// 		OLED_SetPos(x1, y);
// 		for (n = x1; n <= x2; n++)
// 		{
// 			OLED_WR_Byte(0xff, OLED_DATA);
// 		}
// 	}
// 	OLED_SetPos(x1, y2 >> 3);
// 	for (n = x1; n <= x2; n++)
// 	{
// 		OLED_WR_Byte((0x01 << (y2 % 8) + 1) - 1, OLED_DATA);
// 	}
// }


void OLED_Init(void) {

	OLED_RST_Set();
	OLED_DELAY();
	OLED_RST_Clr();
	OLED_DELAY();
	OLED_RST_Set();

	OLED_WR_Byte(0xAE, OLED_CMD);
	OLED_WR_Byte(0x00, OLED_CMD);
	OLED_WR_Byte(0x10, OLED_CMD);
	OLED_WR_Byte(0x40, OLED_CMD);

	OLED_WR_Byte(0x81, OLED_CMD);
	OLED_WR_Byte(0xCF, OLED_CMD);
	OLED_WR_Byte(0xA1, OLED_CMD);
	OLED_WR_Byte(0xC8, OLED_CMD);
	OLED_WR_Byte(0xA6, OLED_CMD);
	OLED_WR_Byte(0xA8, OLED_CMD);
	OLED_WR_Byte(0x3f, OLED_CMD);
	OLED_WR_Byte(0xD3, OLED_CMD);
	OLED_WR_Byte(0x00, OLED_CMD);
	OLED_WR_Byte(0xd5, OLED_CMD);
	OLED_WR_Byte(0x80, OLED_CMD);
	OLED_WR_Byte(0xD9, OLED_CMD);
	OLED_WR_Byte(0xF1, OLED_CMD);
	OLED_WR_Byte(0xDA, OLED_CMD);
	OLED_WR_Byte(0x12, OLED_CMD);
	OLED_WR_Byte(0xDB, OLED_CMD);
	OLED_WR_Byte(0x40, OLED_CMD);
	OLED_WR_Byte(0x20, OLED_CMD);
	OLED_WR_Byte(0x02, OLED_CMD);
	OLED_WR_Byte(0x8D, OLED_CMD);
	OLED_WR_Byte(0x14, OLED_CMD);
	OLED_WR_Byte(0xA4, OLED_CMD);
	OLED_WR_Byte(0xA6, OLED_CMD);
	OLED_WR_Byte(0xAF, OLED_CMD);
	OLED_WR_Byte(0xAF, OLED_CMD);
	OLED_Clear();
	OLED_SetPos(0, 0);
}
